home *** CD-ROM | disk | FTP | other *** search
/ Plug-In Power Pack for Netscape Communicator / Plug-In Power Pack for Netscape Communicator.iso / plugins / dataviews / dvtools / examples / programs / dp_manip.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-08  |  21.0 KB  |  644 lines

  1. #ifndef lint
  2. static char SccsId[]= "@(#)dp_manip.c    V1.30    3/22/95";
  3. #endif
  4. /*
  5. |    file -- dp_manip.c
  6. |====================================================================
  7. |
  8. |    This program shows how to use DV-Tools to manipulate drawports.
  9. |    The program loads in a previously created view and
  10. |    presents a menu of choices to the user.  The user may
  11. |    pan the drawport to a selected point in the drawing;
  12. |    she may zoom in or out by a factor of 2.0 (makes the
  13. |    apparent size of the drawing twice as big or twice as small);
  14. |    she may zoom to a specified area of the drawing;
  15. |    and she may reset the drawport to its original state.
  16. |    Also, this example shows how a call to TscReset is used to
  17. |    reset the drawport after a window is resized (in a window
  18. |    system).
  19. |
  20. |    This example does not update dynamics or input objects.
  21. |
  22. |    Select the QUIT option to exit the program.
  23. |
  24. |=====================================================================
  25. */
  26. #include <windows.h>
  27.  
  28. /* DV-Tools header files */
  29. #include "std.h"            /* <stdio.h> etc., scalar & macro definitions */
  30. #include "dvstd.h"          /* public types & constants */
  31. #include "dvtools.h"        /* constants used by T routines */
  32. #include "dvGR.h"           /* constants used by window mgt & GR routines */
  33. #include "VOstd.h"          /* constants used by VO & VOob routines */
  34. #include "Tfundecl.h"       /* T routines (screens, drawports & views) */
  35. #include "VOfundecl.h"      /* VO routines (objects) */
  36. #include "VUerfundecl.h"    /* VUer routines (event handling routines) */
  37. #include "VUfundecl.h"      /* VU routines (utilities) */
  38.  
  39.  
  40. /* Constants */
  41. #define  DVPATH            (char *)NULL
  42. #define  DISPFORMS_STB     (char *)NULL
  43. #define  DVDEVICE          (char *)NULL
  44. #define  DVCOLORTABLE      (char *)NULL
  45. #define  VIEW_NAME         "move_objs.v"
  46. #define  SCREEN_VIEWPORT   (RECTANGLE *)NULL
  47. #define  ENTIRE_DRAWPORT   (RECTANGLE *)NULL
  48. #define  MENU_CLIENT       (OBJECT)1
  49. #define  VSCROLL_CLIENT       (OBJECT)2
  50. #define  HSCROLL_CLIENT    (OBJECT)3
  51. #define  ZOOM_IN       (int)1
  52. #define  ZOOM_OUT       (int)2
  53. #define  ZOOM_TO       (int)3
  54. #define  PAN           (int)4
  55. #define  RESET_DP       (int)5
  56. #define  QUIT           (int)6
  57. #define  EXPOSE_LABEL       (int)1
  58. #define  RESIZE_LABEL       (int)2
  59.  
  60. /* Information to be passed on to the service routine */
  61. typedef struct
  62. {
  63.   DRAWPORT view_dp, main_dp;
  64.   float *vscroll_data, *hscroll_data, *menu_data;
  65.   OBJECT MessageString, menu_obj, hscroll_obj, vscroll_obj;
  66.   DV_POINT CurrentCenter;
  67.   int quit;
  68. } INFO;
  69.  
  70. /* Whole world rectangle, (-16384, -16384) to (16383, 16383)*/
  71. LOCAL RECTANGLE whole_world =
  72. {XMIN, YMIN, XMAX, YMAX};
  73.  
  74. /* Global forward function declarations */
  75. int ExposeResizeHandler V_P_((OBJECT scr_client, EVENT_REQUEST request,
  76.                   int label, OBJECT loc, ADDRESS args));
  77. int HandleInput V_P_((OBJECT client, EVENT_REQUEST er,
  78.               int label, OBJECT loc, ADDRESS args));
  79.  
  80. /* Local forward function declarations */
  81. LOCAL void ResetDrawport V_P_((INFO *info));
  82. LOCAL void PanDrawportTo V_P_((INFO *info, DV_POINT *newpt));
  83. LOCAL void Pan V_P_((INFO *info));
  84. LOCAL void UserZoomTo V_P_((INFO *info));
  85. LOCAL OBJECT GetLocationInDrawport V_P_((INFO *info, char *msg));
  86.  
  87.  
  88. /*
  89.  *   MAIN PROGRAM
  90.  */
  91. int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  92.                      LPSTR lpCmdLine,  int nCmdShow  )
  93. {
  94.   /*
  95.    *  program arguments
  96.    *      argv[1] - display device name (default is to use DVDEVICE)
  97.    *      argv[2] - view name (default is move_objs.v)
  98.    */
  99.  
  100.   /* Define & initialize device name and view filename */
  101.   char *device_name = DVDEVICE; /* default device name */
  102.   char *view_name = VIEW_NAME;  /* default view name */
  103.  
  104.   /* Define display variables */
  105.   OBJECT screen;                /* display device, the window */
  106.   VIEW view, main_view;         /* picture representation of the view file */
  107.  
  108.   /* Control loop variables */
  109.   OBJECT location;              /* the event representation */
  110.   char key;
  111.  
  112.   /* Input object related variables */
  113.   OBJECT drawing;               /* graphical representation of screen */
  114.   ADDRESS *vdplist;             /* variable descriptor list for menu */
  115.   int numvars;                  /* number of vdps in list */
  116.   INFO info;                    /* struct passed to service result routine */
  117.   int event_req_status;         /* status of event requests */
  118.  
  119.   /* Layout rectangle variables */
  120.   RECTANGLE box,                /* world coordinate drawport area */
  121.             svp_delta,          /* allowance for line thickness */
  122.             vvp;                /* virtual coordinate drawport area */
  123.  
  124.   /* Other variables */
  125.   OBJECT off_color;             /* color object represent off drawing color */
  126.  
  127.   int argc;
  128.   char **argv;
  129.  
  130.   make_argv(&argc,&argv,GetCommandLine());
  131.  
  132.   /*--------------------
  133.    *   Initialization
  134.    *
  135.    *   TInit:  perform the initialization of DV-Tools
  136.    *           TInit reads your configuration file and any
  137.    *           environment variables or logical names set.
  138.    */
  139.   TInit (DVPATH, DISPFORMS_STB);
  140.  
  141.   /*
  142.    *   TscOpenSet: open a device as a screen object using
  143.    *               specified attributes
  144.    *
  145.    *   Set exposure block to YES to insure the window
  146.    *   is ready for drawing when TdpDraw is called.
  147.    */
  148.   if (argc > 1)
  149.     device_name = argv[1];
  150.   screen = TscOpenSet (device_name, DVCOLORTABLE,
  151.                        V_X_EXPOSURE_BLOCK, YES,
  152.                        V_ACTIVE_CURSOR, V_END_OF_LIST);
  153.   if (!screen)
  154.     {
  155.       printf ("Must specify device on command line or");
  156.       printf (" in DataViews configuration file.\n");
  157.       S_EXIT (EXIT_ERR);
  158.     }
  159.  
  160.   /*
  161.    *   VOscWinEventMask:  sets the screen's window event mask
  162.    */
  163.   VOscWinEventMask ((ULONG) V_KEYPRESS | V_BUTTONPRESS
  164.                             | V_EXPOSE | V_RESIZE | V_MOTIONNOTIFY,
  165.             (ULONG) 0);
  166.  
  167.   /*
  168.    *   VUerWinEventPost:  Posts a request for a window event.
  169.    *
  170.    *   Post event requests for "window" events - Expose and Resize.
  171.    */
  172.   VUerWinEventPost (screen, (VUERFCNFUNPTR)ExposeResizeHandler,
  173.                     (ADDRESS) NULL, 0, EXPOSE_LABEL,
  174.                     (ULONG) VUER_EXPOSE_EVENT);
  175.   VUerWinEventPost (screen, (VUERFCNFUNPTR)ExposeResizeHandler,
  176.                     (ADDRESS) NULL, 0, RESIZE_LABEL,
  177.                     (ULONG) VUER_RESIZE_EVENT);
  178.  
  179.   /*
  180.    *   TviLoad:   Load a view in from a file, either a
  181.    *              user supplied view or default view file move_objs.v
  182.    */
  183.   if (argc == 3)
  184.     view_name = argv[2];
  185.   view = TviLoad (view_name);
  186.   if (!view)
  187.     {
  188.       printf ("Could not load view from file ");
  189.       printf ("%s.\n", view_name);
  190.       S_EXIT (EXIT_ERR);
  191.     }
  192.  
  193.   /* Set the off drawing color to be used. This is done to show
  194.    * the off drawing area when zooming and panning operations
  195.    * are performed.
  196.    */
  197.   off_color = VOcoCreate (COLOR_COMPONENTS, 165, 165, 165);
  198.   VOdrOffcolor (off_color);
  199.  
  200.   /* Load the control view and create a drawport to fit the entire screen.*/
  201.   main_view = TviLoad ("dp_manip.v");
  202.   info.main_dp = TdpCreateStretch (screen, main_view,
  203.                                    SCREEN_VIEWPORT, &whole_world);
  204.  
  205.   /*
  206.    * Get drawing object. Then obtain the object called MessageString
  207.    * from the drawing and save it in the structure, info.
  208.    */
  209.   drawing = TviGetDrawing (main_view);
  210.   info.MessageString = TdrGetNamedObject (drawing, "MessageString");
  211.  
  212.   /*
  213.    *   TdrGetNamedObject: Get a named object from a drawing
  214.    *   VOobBox:           Get an object's bounding box
  215.    *                    gets the rectangular area where the drawport will be
  216.    *                    shown (may ignore svp_delta in this case)
  217.    *
  218.    *   Create a display drawport using the view area's bounding box.
  219.    */
  220.   VOobBox (TdrGetNamedObject (drawing, "view.area"), &box, &svp_delta);
  221.  
  222.   /* Convert from world to virtual coordinates.  */
  223.   vvp.ll.x = box.ll.x + XMAX;
  224.   vvp.ll.y = box.ll.y + YMAX;
  225.   vvp.ur.x = box.ur.x + XMAX;
  226.   vvp.ur.y = box.ur.y + YMAX;
  227.  
  228.   /*
  229.    *   TdpCreateStretch: Create a drawport
  230.    *                "drawport" is attached to the screen object, "screen"
  231.    *                "view[i]" is the view to be displayed on the screen
  232.    *                "vvp" specifies the screen viewport, here the
  233.    *                      rectangular area named area_name[i]
  234.    *                "whole_world" specifies the portion of the view to be
  235.    *                      displayed, here the whole view
  236.    *                The whole view will be stretched to fit in the drawport
  237.    */
  238.   info.view_dp = TdpCreateStretch (screen, view, &vvp, &whole_world);
  239.  
  240.   /* Erase the screen and draw the contents of both drawports */
  241.   TscErase (screen);
  242.   TdpDraw (info.main_dp);
  243.   TdpDraw (info.view_dp);
  244.  
  245.   /*
  246.    *   Get the text menu input object and the scroll bars.
  247.    *   Obtain the vdp lists for the input objects then find
  248.    *   the data source variable which each vdp is linked to.
  249.    *   Next, obtain the buffer address which the data source
  250.    *   variable is pointing to. Finally, post service result
  251.    *   requests to monitor the interaction with the input objects.
  252.    */
  253.   info.menu_obj = TdrGetNamedObject (drawing, "menu");
  254.   VOinGetVarList (info.menu_obj, &vdplist, &numvars);
  255.   info.menu_data =
  256.     (float *) TdsvGetBuffer (TvdGetDataSourceVariable (vdplist[0]));
  257.  
  258.   VUerServiceResultPost (MENU_CLIENT, (VUERFCNFUNPTR)HandleInput,
  259.                          (ADDRESS) & info, 0, info.menu_obj,
  260.                          INPUT_DONE, 0);
  261.  
  262.   info.vscroll_obj = TdrGetNamedObject (drawing, "vert_scroll");
  263.   VOinGetVarList (info.vscroll_obj, &vdplist, &numvars);
  264.   info.vscroll_data =
  265.     (float *) TdsvGetBuffer (TvdGetDataSourceVariable (vdplist[0]));
  266.  
  267.   VUerServiceResultPost (VSCROLL_CLIENT, (VUERFCNFUNPTR)HandleInput,
  268.                          (ADDRESS) & info, 0, info.vscroll_obj,
  269.                          INPUT_DONE | INPUT_ACCEPT, 0);
  270.  
  271.   info.hscroll_obj = TdrGetNamedObject (drawing, "horz_scroll");
  272.   VOinGetVarList (info.hscroll_obj, &vdplist, &numvars);
  273.   info.hscroll_data =
  274.     (float *) TdsvGetBuffer (TvdGetDataSourceVariable (vdplist[0]));
  275.  
  276.   VUerServiceResultPost (HSCROLL_CLIENT, (VUERFCNFUNPTR)HandleInput,
  277.                          (ADDRESS) & info, 0, info.hscroll_obj,
  278.                          INPUT_DONE | INPUT_ACCEPT, 0);
  279.  
  280.   /* Initialize scale and center value and quit flag */
  281.   info.CurrentCenter.x = 0;
  282.   info.CurrentCenter.y = 0;
  283.   info.quit = NO;
  284.   FOREVER
  285.   {
  286.     location = VOloWinEventPoll (V_WAIT);
  287.     event_req_status = VUerHandleLocEvent (location);
  288.  
  289.     /*
  290.      * If the return value of VUerHandleLocEvent is INPUT_UNUSED
  291.      * then check for keypress or buttonpress events which
  292.      * represent one of the exit keys.
  293.      */
  294.     if (event_req_status == INPUT_UNUSED)
  295.       {
  296.         /*
  297.          *  VOloType:  returns the type of event.  These types
  298.          *             match event types specified in VOscWinEventMask.
  299.          */
  300.         switch (VOloType (location))
  301.           {
  302.           case V_KEYPRESS:
  303.             /*
  304.              *  Check key selected.
  305.              *  If the key symbol represents the characters 'q'
  306.              *  or 'Q' then exit the program.
  307.              */
  308.             key = VOloKey (location);
  309.             if (key == '\014')
  310.               {
  311.                 TscReset (screen);
  312.                 TdpDraw (info.main_dp);
  313.                 TdpDraw (info.view_dp);
  314.               }
  315.             else if (key == 'q' || key == 'Q')
  316.               info.quit = YES;
  317.             break;
  318.  
  319.           case V_BUTTONPRESS:
  320.             /*
  321.              *  Check button selected.
  322.              *  The right mouse button exits the program.
  323.              */
  324.             switch (VOloButton (location))
  325.               {
  326.               case 3:
  327.                 info.quit = YES;
  328.                 break;
  329.  
  330.               default:
  331.                 break;
  332.               }
  333.             break;
  334.  
  335.           default:
  336.             break;
  337.           }
  338.       }
  339.  
  340.     if (info.quit == YES)
  341.       break;
  342.     TdpDrawNext (info.main_dp);
  343.   }
  344.  
  345.   /*--------------------
  346.    *   Termination
  347.    *
  348.    *   TscErase:     Erase the entire screen in the default
  349.    *                 background color
  350.    *   TdpDestroy:   Destroy the drawport,
  351.    *   TviDestroy:   Destroy the view, freeing the allocated memory
  352.    *   TscCloseCurrentScreen:  Close the current display screen
  353.    *   TTerminate:   Perform the clean-up for DV-Tools
  354.    */
  355.   TscErase (screen);
  356.   TdpDestroy (info.main_dp);
  357.   TdpDestroy (info.view_dp);
  358.   TviDestroy (view);
  359.   TviDestroy (main_view);
  360.   TscCloseCurrentScreen ();
  361.   TTerminate ();
  362.   return EXIT_OK;
  363. }
  364.  
  365.  
  366. /*--------------------
  367.  * ExposeResizeHandler -- Service Routine which is called in
  368.  *       response to "window" events (Expose and Resize).  The
  369.  *       event requests that this routine services are posted
  370.  *       with VUerWinEventPost (above).  The "label" argument
  371.  *       tells the routine which request (Expose or Resize)
  372.  *       caused the routine to be called.
  373.  */
  374. /*ARGSUSED*/
  375. int 
  376. ExposeResizeHandler (scr_client, request, label, loc, args)
  377.      OBJECT scr_client;
  378.      EVENT_REQUEST request;
  379.      int label;
  380.      OBJECT loc;
  381.      ADDRESS args;
  382. {
  383.   switch (label)
  384.     {
  385.       /*
  386.        *  VOloRegion:  Returns a rectangle representing the
  387.        *               exposed region on the screen.
  388.        *  TscRedraw:   After erasing, redraws all the drawports
  389.        *               in the screen.
  390.        *  A portion of the window has been exposed and needs
  391.        *  to be redrawn.
  392.        */
  393.     case EXPOSE_LABEL:
  394.       TscRedraw (scr_client, VOloRegion (loc));
  395.       break;
  396.  
  397.       /*
  398.        *  The window size has been changed.
  399.        *  TscReset:  Resets all screen drawports after
  400.        *             window resizing
  401.        */
  402.     case RESIZE_LABEL:
  403.       TscReset (scr_client);
  404.       break;
  405.     }
  406.  
  407.   return INPUT_USED;
  408. }
  409.  
  410. /*--------------
  411.  *   HandleInput -- Perform the appropriate action based
  412.  *      on the user's interaction with the particular
  413.  *      input object.  This function is called for the
  414.  *      menu and scrollbars used in the control view.
  415.  */
  416. /*ARGSUSED*/
  417. int 
  418. HandleInput (client, er, label, loc, args)
  419.      OBJECT client;      /* client id posting service result req */
  420.      EVENT_REQUEST er;   /* service result posting routine return value */
  421.      int label;          /* label to identify service result request */
  422.      OBJECT loc;         /* location object */
  423.      ADDRESS args;       /* argument structure */
  424. {
  425.   INFO *info = (INFO *) args;
  426.   DV_POINT desired_center;
  427.  
  428.   switch ((int) client)
  429.     {
  430.     case MENU_CLIENT:
  431.       switch ((int) (*info->menu_data))
  432.         {
  433.         case ZOOM_IN:
  434.           TdpZoom (info->view_dp, (double) 2.0);
  435.           break;
  436.         case ZOOM_OUT:
  437.           TdpZoom (info->view_dp, (double) 0.5);
  438.           break;
  439.         case ZOOM_TO:
  440.           UserZoomTo (info);
  441.           break;
  442.         case PAN:
  443.           Pan (info);
  444.           break;
  445.         case RESET_DP:
  446.           ResetDrawport (info);
  447.           break;
  448.         case QUIT:
  449.           info->quit = YES;
  450.           break;
  451.         }
  452.  
  453.       /* modify sliders' buffers so sliders will reflect change */
  454.       *info->hscroll_data = -1 * info->CurrentCenter.x;
  455.       *info->vscroll_data = -1 * info->CurrentCenter.y;
  456.  
  457.       /* set menu buffer to unhighlight button just pressed */
  458.       *info->menu_data = 0;
  459.       break;
  460.  
  461.     case VSCROLL_CLIENT:
  462.       desired_center.x = info->CurrentCenter.x;
  463.       desired_center.y = (DV_COORD) *info->vscroll_data * -1;
  464.       PanDrawportTo (info, &desired_center);
  465.       break;
  466.  
  467.     case HSCROLL_CLIENT:
  468.       desired_center.x = (DV_COORD) *info->hscroll_data * -1;
  469.       desired_center.y = info->CurrentCenter.y;
  470.       PanDrawportTo (info, &desired_center);
  471.       break;
  472.     }
  473.  
  474.   if (!info->quit)
  475.     TdpRedraw (info->view_dp, ENTIRE_DRAWPORT, YES);
  476.  
  477.   return INPUT_USED;
  478. }
  479.  
  480. /*----------------
  481.  *   ResetDrawport -- User selected to Reset the view
  482.  *      drawport. Return the view drawport to the original
  483.  *      display. Reset the current scale and center point.
  484.  */
  485. LOCAL void 
  486. ResetDrawport (info)
  487.      INFO *info;
  488. {
  489.   info->CurrentCenter.x = 0;
  490.   info->CurrentCenter.y = 0;
  491.   TdpZoomTo (info->view_dp, ENTIRE_DRAWPORT);
  492. }
  493.  
  494.  
  495. /*----------------
  496.  *   PanDrawportTo -- Pan the drawport to the passed
  497.  *      center point.
  498.  */
  499. LOCAL void 
  500. PanDrawportTo (info, newpt)
  501.      INFO *info;
  502.      DV_POINT *newpt;
  503. {
  504.   info->CurrentCenter.x = newpt->x;
  505.   info->CurrentCenter.y = newpt->y;
  506.   TdpPan (info->view_dp, newpt);
  507. }
  508.  
  509.  
  510. /*--------------
  511.  *   Pan -- Pan the drawport to the specified
  512.  *      center point.
  513.  */
  514. LOCAL void 
  515. Pan (info)
  516.      INFO *info;
  517. {
  518.   OBJECT location;
  519.   DV_POINT *center_pt;
  520.  
  521.   /* Obtain a location for the center point from the user. */
  522.   location = GetLocationInDrawport (info, "Select new center point.");
  523.  
  524.   /* Obtain the world coordinates of the location point. If the user
  525.      selected a point outside the drawing area, the world coordinates
  526.      of the location object will be NULL. In this case, we reprompt
  527.      the user for another center point selection. */
  528.   while (!(center_pt = (DV_POINT *) VOloWcpGet (location)))
  529.     location = GetLocationInDrawport (info,
  530.       "Invalid point selection.\nPick center point in drawing area.");
  531.  
  532.   /* Pan the drawport with the user selected center point. */
  533.   PanDrawportTo (info, center_pt);
  534. }
  535.  
  536. /*--------------
  537.  *   UserZoomTo -- User selected to Zoom To a particular region.
  538.  *      The user is prompted for the rectangle representing the
  539.  *      region to zoom to. TdpZoomTo is called to alter the
  540.  *    drawport display based on the selected rectangle.
  541.  */
  542. LOCAL void 
  543. UserZoomTo (info)
  544.      INFO *info;
  545. {
  546.   char *old_msg;
  547.   OBJECT location;
  548.   RECTANGLE ZoomVp;
  549.   DV_POINT *point;
  550.  
  551.   old_msg = VUstrClone (VOtxGetString (info->MessageString));
  552.   TdpEraseObject (info->main_dp, info->MessageString);
  553.   VOtxSetString (info->MessageString, " ");
  554.  
  555.   /* Prompt user for first corner of area to zoom. A point
  556.      selected outside of the drawing area is an invalid point
  557.      selection and the user is reprompt for a selection. */
  558.   location = GetLocationInDrawport (info,
  559.                                     "Select first corner of area to zoom.");
  560.   while (!(point = (DV_POINT *) VOloWcpGet (location)))
  561.     location = GetLocationInDrawport (info,
  562.                "Invalid point selection.\n Pick corner point in drawing area.");
  563.   ZoomVp.ll.x = point->x;
  564.   ZoomVp.ll.y = point->y;
  565.  
  566.   /* Prompt user for second corner of area to zoom. A point
  567.      selected outside of the drawing area is an invalid point
  568.      selection and the user is reprompt for a selection. */
  569.   location = GetLocationInDrawport (info,
  570.                                     "Select second corner of area to zoom.");
  571.   FOREVER
  572.   {
  573.     point = (DV_POINT *) VOloWcpGet (location);
  574.     if (!point)
  575.       location = GetLocationInDrawport (info,
  576.       "Invalid point selection.\n Pick corner point in drawing area.");
  577.     else if ((point->x == ZoomVp.ll.x) || (point->y == ZoomVp.ll.y))
  578.       location = GetLocationInDrawport (info,
  579. "Zoom rectangle has zero length on one side.\n Pick a different corner point.");
  580.     else
  581.       break;
  582.   }
  583.   ZoomVp.ur.x = point->x;
  584.   ZoomVp.ur.y = point->y;
  585.  
  586.   /* Set the message string back to the original message. */
  587.   VOtxSetString (info->MessageString, old_msg);
  588.   S_FREE (old_msg);
  589.   TdpDrawObject (info->main_dp, info->MessageString);
  590.  
  591.   VOuVpSort (&ZoomVp);
  592.   TdpZoomTo (info->view_dp, &ZoomVp);
  593. }
  594.  
  595.  
  596.  
  597. /*------------------------
  598.  *   GetLocationInDrawport -- Prompt user to select point in viewing
  599.  *      drawport. The parameter msg represents the prompt to be
  600.  *      displayed to the user.
  601.  */
  602. LOCAL OBJECT 
  603. GetLocationInDrawport (info, msg)
  604.      INFO *info;
  605.      char *msg;
  606. {
  607.   char *old_msg;
  608.   OBJECT location;
  609.  
  610.   old_msg = VUstrClone (VOtxGetString (info->MessageString));
  611.   TdpEraseObject (info->main_dp, info->MessageString);
  612.   VOtxSetString (info->MessageString, msg);
  613.   TdpDrawObject (info->main_dp, info->MessageString);
  614.  
  615.   VOscWinEventMask ((ULONG) V_BUTTONPRESS | V_RESIZE | V_EXPOSE, (ULONG) 0);
  616.   VOinState (info->menu_obj, INACTIVE);
  617.   VOinState (info->vscroll_obj, INACTIVE);
  618.   VOinState (info->hscroll_obj, INACTIVE);
  619.  
  620.   while (1)
  621.     {
  622.       location = VOloWinEventPoll (V_WAIT);
  623.       if (VUerHandleLocEvent (location) == INPUT_UNUSED)
  624.         {
  625.           if (TloGetSelectedDrawport (location) != info->view_dp)
  626.             continue;
  627.           break;
  628.         }
  629.     }
  630.   TdpEraseObject (info->main_dp, info->MessageString);
  631.   VOtxSetString (info->MessageString, old_msg);
  632.   S_FREE (old_msg);
  633.   TdpDrawObject (info->main_dp, info->MessageString);
  634.  
  635.   VOscWinEventMask ((ULONG) V_KEYPRESS | V_BUTTONPRESS
  636.                             | V_EXPOSE | V_RESIZE | V_MOTIONNOTIFY,
  637.             (ULONG) 0);
  638.   VOinState (info->menu_obj, ACTIVE);
  639.   VOinState (info->vscroll_obj, ACTIVE);
  640.   VOinState (info->hscroll_obj, ACTIVE);
  641.  
  642.   return location;
  643. }
  644.